package com.bcfn.bshop.common.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.bcfn.bshop.common.dao.BaseDao;
import com.bcfn.bshop.common.dto.BaseDto;
import com.bcfn.bshop.common.dto.DataGridDto;
import com.bcfn.bshop.common.exception.ErrorInfoException;
import com.bcfn.bshop.common.model.BaseModel;
import com.bcfn.bshop.common.utils.DtoBuilder;

/**
 * 
 * @author LiangGuoNing
 * @create 2019年2月10日 上午12:59:14
 * @copyright
 * @modify
 */
public abstract class BaseServiceImpl<ID extends Serializable,M extends BaseModel<ID>,Dto extends BaseDto<ID>> implements BaseService<ID,Dto>{

	private Class<Dto> dtoClazz;
	
	private Class<M> modelClazz;
	
	public BaseServiceImpl(Class<M> modelClazz,Class<Dto> dtoClazz) {
		this.dtoClazz = dtoClazz;
		this.modelClazz = modelClazz;
	}
	
	@Transactional(readOnly=true)
	public DataGridDto<Dto> search(Dto dto) {
		DataGridDto<Dto> dataGridDto = null;
		try {
			M model = DtoBuilder.buildModel(dto,modelClazz);
			List<M> models = this.getBaseDao().search(model);
			List<Dto> dtos = null;
			if(models != null) {
				dtos = new ArrayList<Dto>();
				for(M m : models) {
					Dto d = DtoBuilder.buildDto(m,dtoClazz);
					dtos.add(d);
				}
			}
			
			dataGridDto = new DataGridDto<Dto>();
			dataGridDto.setPageNo(dto.getPageNo());
			dataGridDto.setPageSize(dto.getPageSize());
			dataGridDto.setDatas(dtos);
		}catch(Exception e) {
			throw new RuntimeException(e);
		}
		return dataGridDto;
	}

	@Transactional(readOnly=true)
	public Dto get(ID id) {
		Dto itemDto = null;
		try {
			M item = this.getBaseDao().get(id);
			itemDto = DtoBuilder.buildDto(item,dtoClazz);
		} catch (ErrorInfoException e) {
			throw new RuntimeException(e);
		}
		return itemDto;
	}

	@Transactional
	public void update(Dto dto) {
		M model = null;
		try {
			model = DtoBuilder.buildModel(dto, modelClazz);
			this.getBaseDao().update(model);
		} catch (ErrorInfoException e) {
			throw new RuntimeException(e);
		}
	}

	@Transactional
	public Dto save(Dto dto) {
		M model = null;
		try {
			model = DtoBuilder.buildModel(dto, modelClazz);
			this.getBaseDao().save(model);
			dto.setId(model.getId());
		} catch (ErrorInfoException e) {
			throw new RuntimeException(e);
		}
		return dto;
	}

	@Transactional
	public void delete(ID id) {
		this.getBaseDao().delete(id);
	}

	public abstract BaseDao<ID,M> getBaseDao();
	
}
